home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / quarkpy / qutils.py < prev   
Text File  |  2004-01-05  |  17KB  |  603 lines

  1. """   QuArK  -  Quake Army Knife
  2.  
  3. Various constants and routines
  4. """
  5. #
  6. # Copyright (C) 1996-99 Armin Rigo
  7. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  8. # FOUND IN FILE "COPYING.TXT"
  9. #
  10.  
  11.  
  12. #$Header: /cvsroot/quark/runtime/quarkpy/qutils.py,v 1.24 2003/12/18 21:51:46 peter-b Exp $
  13.  
  14. import quarkx
  15.  
  16. # a few colors
  17. BLACK     = 0x000000
  18. MAROON    = 0x000080
  19. GREEN     = 0x008000
  20. OLIVE     = 0x008080
  21. NAVY      = 0x800000
  22. PURPLE    = 0x800080
  23. TEAL      = 0x808000
  24. GRAY      = 0x808080
  25. SILVER    = 0xC0C0C0
  26. RED       = 0x0000FF
  27. LIME      = 0x00FF00
  28. YELLOW    = 0x00FFFF
  29. BLUE      = 0xFF0000
  30. FUCHSIA   = 0xFF00FF
  31. AQUA      = 0xFFFF00
  32. LTGRAY    = 0xC0C0C0
  33. DKGRAY    = 0x808080
  34. WHITE     = 0xFFFFFF
  35. NOCOLOR   = 0x1FFFFFFF    # for map view backgrounds and model components
  36.  
  37. # panels 'align' values
  38. LEFT      = "left"
  39. RIGHT     = "right"
  40. TOP       = "top"
  41. BOTTOM    = "bottom"
  42. FULL      = "full"
  43. NOALIGN   = None
  44.  
  45. # toolbars 'dock' values
  46. TOPDOCK   = "topdock"
  47. BOTTOMDOCK= "bottomdock"
  48. LEFTDOCK  = "leftdock"
  49. RIGHTDOCK = "rightdock"
  50. NODOCK    = None
  51.  
  52. # window states
  53. RESTORED  = 0       # normal
  54. MINIMIZED = 1
  55. MAXIMIZED = 2
  56.  
  57. # filedialogbox
  58. SAVEDIALOG     = 1
  59. MULTIPLEFILES  = 64
  60.  
  61. # setupset
  62. SS_GENERAL     = 0
  63. SS_GAMES       = 1
  64. SS_MAP         = 2
  65. SS_MODEL       = 3
  66. SS_TOOLBARS    = 4
  67.  
  68. # floating windows flags
  69. FWF_NOCAPTION  = 1
  70. FWF_NOCLOSEBOX = 2
  71. FWF_NORESIZE   = 4
  72. FWF_POPUPCLOSE = 8
  73. FWF_NOESCCLOSE = 16
  74. FWF_KEEPFOCUS  = 32
  75.  
  76. # internal objects' "flags" value !!! WARNING !!! DO NOT MODIFY unless you know what you're doing !
  77. OF_TVSUBITEM         = 1   # all objects in a tree-view except top-level
  78. OF_TVINVISIBLE       = 2   # present but invisible in the tree-view
  79. OF_TVALREADYEXPANDED = 4   # node has been expanded once
  80. OF_TVEXPANDED        = 8   # node is expanded
  81. OF_ONDISK            = 16  # has not been loaded yet (loading is automatic when Python code reads the object's Specifics or sub-items)
  82. OF_FILELINK          = 32  # is a file link
  83. OF_WARNBEFORECHANGE  = 64  # warn the user before he makes changes
  84. OF_MODIFIED          = 128 # modified by the user
  85.  
  86. # values of the ';view' Specific (as text) of TreeMapGroup objects
  87. # !! Must match the constants in QkMapObjects.PAS !!
  88. VF_GRAYEDOUT        = 1    # whole group is grayed out
  89. VF_HIDDEN           = 2    # whole group is hidden
  90. VF_IGNORETOBUILDMAP = 4    # the group is ignored when writing the .map file with the SO_IGNORETOBUILD flag
  91. VF_HIDEON3DVIEW     = 8    # not displayed on textured views
  92. VF_CANTSELECT       = 16   # the objects in this group can't be selected by clicking on the map view
  93.  
  94. # values of the 'saveflags' Specific (as integer) of Map objects, to control how it should be saved
  95. # !! Must match the constants in QkMapObjects.PAS !!
  96. SO_SELONLY         = 1    # only the selection is saved
  97. SO_IGNORETOBUILD   = 2    # the groups marked VF_IGNORETOBUILDMAP are not saved
  98. #SO_DISABLEENHTEX   = 4    # don't write the "//TX1"-style comments required by TXQBSP for enhanced texture positionning
  99. SO_DISABLEFPCOORD  = 8    # don't write floating-point coordinates in .map files, round all values
  100. #SO_ENABLEBRUSHPRIM = 16   # enable brush primitives format
  101. SO_USEINTEGRALVERTICES = 64 # use integral vertices as threepoints if possible
  102.  
  103. # icon indexes of internal objects (to be used with quarkx.seticons)
  104. iiUnknownFile           = 0
  105. iiExplorerGroup         = 1
  106. iiQuakeC                = 2
  107. iiBsp                   = 3
  108. iiToolBox               = 4
  109. iiUnknown               = 5
  110. iiPakFolder             = 6
  111. iiLinkOverlay           = 7
  112. iiModel                 = 8
  113. iiMap                   = 9
  114. iiPak                   = 10
  115. iiEntity                = 11
  116. iiBrush                 = 12
  117. iiGroup                 = 13
  118. iiDuplicator            = 14
  119. iiPolyhedron            = 15
  120. iiFace                  = 16
  121. iiCfgFolder             = 17
  122. iiCfg                   = 18
  123. iiInvalidPolyhedron     = 19
  124. iiInvalidFace           = 20
  125. iiNewFolder             = 21
  126. iiWad                   = 22
  127. iiTexture               = 23
  128. iiTextureLnk            = 24
  129. iiPcx                   = 25
  130. iiQuArK                 = 26
  131. iiTexParams             = 27
  132. iiQme                   = 28
  133. iiToolbar               = 29
  134. iiToolbarButton         = 30
  135.  # iiFrameGroup            = 31
  136.  # iiSkinGroup             = 32
  137.  # iiSkin                  = 33
  138. iiFrame                 = 34
  139. iiComponent             = 35
  140. iiModelGroup            = 36
  141. iiQCtx                  = 37
  142. iiWav                   = 38
  143. iiCin                   = 39
  144. iiText                  = 40
  145. iiCfgFile               = 41
  146. iiImport                = 42
  147. iiPython                = 43
  148. iiBezier                = 44
  149. #Sprite File Support
  150. iiSprFile               = 45
  151. iiMD3Tag                = 46
  152. iiMD3Bone               = 47
  153. iiFormElement           = 48
  154. iiForm                  = 49
  155. iiFormContext           = 50
  156.  
  157. iiTotalImageCount       = 51
  158.  
  159.  
  160.  
  161. def LoadIconSet(filename, width, transparencypt=(0,0)):
  162.     "Load a set of bitmap files and returns a tuple of image lists."
  163.  
  164.     def loadset(tag, filename=filename, width=width, transparencypt=transparencypt, setup=quarkx.setupsubset(SS_GENERAL, "Display"), cache={}):
  165.         if setup[tag]:
  166.             ext = "-1.bmp"
  167.         else:
  168.             ext = "-0.bmp"
  169.         try:
  170.             return cache[ext]
  171.         except:
  172.             img = quarkx.loadimages(filename + ext, width, transparencypt)
  173.             cache[ext] = img
  174.             return img
  175.  
  176.     # load the unselected version of the icons
  177.     unsel = loadset("Unsel")
  178.  
  179.     # load the selected version of the icons
  180.     sel = loadset("Sel")
  181.  
  182.     # load xxx-2.bmp, the triggered version for on/off buttons
  183.     try:
  184.         trig = quarkx.loadimages(filename + "-2.bmp", width, transparencypt)
  185.         return (unsel, sel, trig)
  186.     except quarkx.error:
  187.         return (unsel, sel)
  188.  
  189.  
  190. #
  191. # equiv to LoadIconSet, just calls a different loadimages
  192. #  to help in leak-tracking
  193. #
  194. def LoadIconSet2(filename, width, transparencypt=(0,0)):
  195.     "Load a set of bitmap files and returns a tuple of image lists."
  196.  
  197.     def loadset(tag, filename=filename, width=width, transparencypt=transparencypt, setup=quarkx.setupsubset(SS_GENERAL, "Display"), cache={}):
  198.         if setup[tag]:
  199.             ext = "-1.bmp"
  200.         else:
  201.             ext = "-0.bmp"
  202.         try:
  203.             return cache[ext]
  204.         except:
  205.             img = quarkx.loadimages(filename + ext, width, transparencypt)
  206.             cache[ext] = img
  207.             return img
  208.  
  209.     # load the unselected version of the icons
  210.     unsel = loadset("Unsel")
  211.  
  212.     # load the selected version of the icons
  213.     sel = loadset("Sel")
  214.  
  215.     # load xxx-2.bmp, the triggered version for on/off buttons
  216.     try:
  217.         trig = quarkx.loadimages(filename + "-2.bmp", width, transparencypt)
  218.         return (unsel, sel, trig)
  219.     except quarkx.error:
  220.         return (unsel, sel)
  221.  
  222.  
  223. def LoadIconSet1(filename, width, transparencypt=(0,0)):
  224.     return LoadIconSet(quarkx.setupsubset(SS_GENERAL, "Display")["IconPath"]+filename, width, transparencypt)
  225.  
  226.  
  227. #
  228. # Map modules loader (map*.py modules require a special load order)
  229. #
  230. def loadmapeditor(what=None):
  231.     global loadmapeditor
  232.     import maputils
  233.     import mapeditor
  234.     import mapmenus
  235.     #---- import the plug-ins ----
  236.     import plugins
  237.     plugins.LoadPlugins("MAP")
  238.  
  239.     def reLoad(what=None):
  240.         #---- import the bezier plug-ins if so stated in Defaults.QRK ----
  241.         #---- and bsp support if we're editing a bsp
  242.         import quarkx
  243.         if what=='bsp':
  244.             plugins.LoadPlugins("BSP")
  245.  
  246.         beziersupport = quarkx.setupsubset()["BezierPatchSupport"]
  247.         if (beziersupport is not None) and (beziersupport == "1"):
  248.             pluginprefixes = quarkx.setupsubset()["BezierPatchPluginPrefixes"]
  249.             if (pluginprefixes is None) or (pluginprefixes == ""):
  250.                 raise "Serious failure in quarkpy.qutils.loadmapeditor: Missing specific-value 'BezierPatchPluginPrefixes' in Defaults.QRK"
  251.             loadmapeditor = lambda: None # next calls to loadmapeditor() do nothing. Everything is now loaded!
  252.             import mapbezier
  253.             for prefix in pluginprefixes.split():
  254.                 plugins.LoadPlugins(prefix.strip())
  255.  
  256.     # force an initial load of bezier-support, if any for the current game-mode.
  257.     reLoad(what)
  258.     # next call to loadmapeditor, will check to see if there is a new need to load
  259.     # bezier/bsp-support, when/if the user changes game-mode in QuArK explorer.
  260.     loadmapeditor = reLoad
  261.  
  262. #
  263. # Model modules loader (mdl*.py modules require a special load order)
  264. #
  265. def loadmdleditor():
  266.     global loadmdleditor
  267.     loadmdleditor = lambda: None    # next calls to loadmdleditor() do nothing
  268.     import mdlutils
  269.     import mdleditor
  270.     import mdlmenus
  271.     #---- import the plug-ins ----
  272.     import plugins
  273.     plugins.LoadPlugins("MDL")
  274.  
  275.  
  276. #
  277. # Icon sets that aren't always loaded should go into this
  278. #   dictionary, indexed by their names.  The dictionary
  279. #   is cleaned up in qmacro.MACRO_shutdown to avoid
  280. #   live pointer memory leaks.
  281. #
  282. ico_dict = {}
  283.  
  284. #
  285. # Putting these two in the ico_dict doesn't achieve
  286. #  any purpose (lots of code gets clunkier, no benefit)
  287. #
  288. # Default icons for the objects
  289. ico_objects = LoadIconSet("images\\objects", 16)
  290.  
  291. # Generic editor icons
  292. ico_editor = LoadIconSet("images\\editor", 16)
  293.  
  294. #
  295. # Variable icons handlers for Quake entities
  296. #
  297.  
  298. def EntityIcon(entity, iconset):
  299.     #
  300.     # Load the Variable icons for Quake Entity objects
  301.     #
  302.     if not ico_dict.has_key('ico_mapents'):
  303.         ico_dict['ico_mapents'] = LoadIconSet("images\\mapents", 16)
  304.     icons = ico_dict['ico_mapents'][iconset]
  305.     #
  306.     # Read the classname of the entity
  307.     #
  308.     name = entity.shortname
  309.     #
  310.     # Analyse the beginning of the classname
  311.     #
  312.     if name[:4]=="item" or name[:6]=="weapon" or name[:9]=="wp_weapon" or name[:4]=="art_":
  313.         return icons[1]
  314.     if name[:4]=="info":
  315.         return icons[2]
  316.     if name[:5]=="light":
  317.         return icons[3]
  318.     if name[:7]=="monster":
  319.         return icons[0]
  320.     return icons[4]
  321.  
  322. def EntityIconSel(entity):
  323.     return EntityIcon(entity, 1)
  324.  
  325. def EntityIconUnsel(entity):
  326.     return EntityIcon(entity, 0)
  327.  
  328.  
  329. #
  330. # Variable icons handlers for duplicators
  331. #
  332.  
  333. def DuplicatorIconUnsel(dup):
  334.     loadmapeditor()
  335.     import mapduplicator
  336.     iconlist, iconindex = mapduplicator.DupManager(dup).Icon
  337.     return iconlist[0][iconindex]
  338.  
  339. def DuplicatorIconSel(dup):
  340.     loadmapeditor()
  341.     import mapduplicator
  342.     iconlist, iconindex = mapduplicator.DupManager(dup).Icon
  343.     return iconlist[1][iconindex]
  344.  
  345.  
  346. #
  347. # Variable icons handlers for groups
  348. #
  349.  
  350. #obj = quarkx.newobj("hello")
  351.  
  352. def GroupIconUnsel(grp, ico_objects_group_set={
  353.   (0,0):ico_objects[0][32],
  354.   (0,1):ico_objects[0][13],
  355.   (4,0):ico_objects[0][33],
  356.   (4,1):ico_objects[0][31]}):
  357.     if grp[";view"]:
  358.         try:
  359.             view = int(grp[";view"])
  360.             return ico_objects_group_set[view&4, not (view&~4)]
  361.         except:
  362.             pass
  363.     return ico_objects[0][13]
  364.  
  365. def GroupIconSel(grp, ico_objects_group_set={
  366.   (0,0):ico_objects[1][32],
  367.   (0,1):ico_objects[1][13],
  368.   (4,0):ico_objects[1][33],
  369.   (4,1):ico_objects[1][31]}):
  370.     if grp[";view"]:
  371.         try:
  372.             view = int(grp[";view"])
  373.             return ico_objects_group_set[view&4, not (view&~4)]
  374.         except:
  375.             pass
  376.     return ico_objects[1][13]
  377. #
  378. # Variable icons handlers for Model objects
  379. #
  380.  
  381. def ModelIcon(modelobj, iconset):
  382.     #
  383.     # Load the Variable icons for Quake Entity objects
  384.     #
  385.     if not ico_dict.has_key('mdlobjs'):
  386.         ico_dict['mdlobjs'] = LoadIconSet("images\\mdlobjs", 16)
  387.     icons = ico_dict['mdlobjs']
  388. #    global ico_mdlobjs
  389. #    try:
  390. #        icons = ico_mdlobjs[iconset]
  391. #    except NameError:
  392. #        ico_mdlobjs = LoadIconSet("images\\mdlobjs", 16)
  393. #        icons = ico_mdlobjs[iconset]
  394.     #
  395.     # Read the type tag of the model
  396.     #
  397.     tag = modelobj.getint("type")
  398.     if tag < len(icons):
  399.         return icons[tag]
  400.     else:
  401.         return ico_objects[iconset][iiUnknown]
  402.  
  403.  
  404. def ModelGroupIconSel(obj):
  405.     return ModelIcon(obj, 1)
  406.  
  407. def ModelGroupIconUnsel(obj):
  408.     return ModelIcon(obj, 0)
  409.  
  410.  
  411. # quarkx.msgbox
  412. MT_WARNING           = 0
  413. MT_ERROR             = 1
  414. MT_INFORMATION       = 2
  415. MT_CONFIRMATION      = 3
  416. MB_YES               = 1
  417. MB_NO                = 2
  418. MB_OK                = 4
  419. MB_CANCEL            = 8
  420. MB_ABORT             = 16
  421. MB_RETRY             = 32
  422. MB_IGNORE            = 64
  423. MB_ALL               = 128
  424. # MB_HELP            = 256
  425. MB_YES_NO_CANCEL     = MB_YES | MB_NO | MB_CANCEL
  426. MB_OK_CANCEL         = MB_OK | MB_CANCEL
  427. MB_ABORT_RETRY_IGNORE= MB_ABORT | MB_RETRY | MB_IGNORE
  428. MR_OK     = 1
  429. MR_CANCEL = 2
  430. MR_ABORT  = 3
  431. MR_RETRY  = 4
  432. MR_IGNORE = 5
  433. MR_YES    = 6
  434. MR_NO     = 7
  435. MR_ALL    = 8
  436.  
  437. # "style" of ":form" objects (convert the numeric value into a string to assign to "style")
  438. GF_GRAY       = 1
  439. GF_EXTRASPACE = 2
  440. GF_NOICONS    = 4
  441. GF_NOBORDER   = 8
  442.  
  443. # file attributes
  444. FA_READONLY     = 1
  445. FA_HIDDEN       = 2
  446. FA_ARCHIVE      = 32
  447. FA_FILENOTFOUND = -1
  448. FA_DELETEFILE   = -1
  449.  
  450.  
  451. SetupRoutines = []
  452.  
  453. def SetupChanged(level):
  454.     "Called by QuArK when the setup is modified."
  455.     for s in SetupRoutines:
  456.         s(level)
  457.  
  458.  
  459. #
  460. # Pool Manager : when you read data that don't change, like icon
  461. # bitmaps, you should store the result in the Pool so that if you
  462. # need the data again you don't have to reload it. So instead of :
  463. #     functionthatloadstuff(argument, ...)
  464. # write :
  465. #     LoadPoolObj(uniquestring, functionthatloadstuff, argument, ...)
  466. #
  467.  
  468. def LoadPoolObj(tag, loadfn, *loadargs):
  469.     "Retrive the content of a pool object, or call a function if not found."
  470.  
  471.     obj = quarkx.poolobj(tag)
  472.     if obj == None:
  473.         obj = apply(loadfn, loadargs)
  474.         quarkx.setpoolobj(tag, obj)
  475.     return obj
  476.  
  477.  
  478. def debug(text):
  479.     import sys
  480.     sys.stderr.write(text+"\n")
  481.  
  482. def MapHotKey(keytag, keyfunc, menu):
  483.     key = quarkx.setupsubset(SS_GENERAL,"HotKeys")[keytag]
  484.     if key:
  485.         menu.shortcuts[key] = keyfunc
  486.  
  487. def MapHotKeyList(keytag, keyfunc, list):
  488.     key = quarkx.setupsubset(SS_GENERAL,"HotKeys")[keytag]
  489.     if key:
  490.         list[key] = keyfunc
  491.  
  492. def clearimagelist(list):
  493.     for (im1, im2) in list:
  494.         del im1
  495.         del im2
  496.  
  497.  
  498.  
  499. #
  500. # Utilities for accessing attributes of objects
  501. #  (class instances) that might not be defined
  502. #
  503. def getAttr(object, attr, default=None):
  504.     if hasattr(object, attr):
  505.         return getattr(object,attr)
  506.     else:
  507.         return default
  508.  
  509. def delAttr(object, attr):
  510.     if hasattr(object, attr):
  511.          delattr(object, attr)
  512.  
  513. def appendToAttr(object, attr, thing):
  514.     if hasattr(object, attr):
  515.         getattr(object,attr).append(thing)
  516.     else:
  517.         setattr(object,attr,[thing])
  518.  
  519. def removeFromAttr(object, attr, thing):
  520.     getattr(object,attr).remove(thing)
  521.     if getattr(object,attr)==[]:
  522.         delattr(object,attr)
  523.  
  524. def hintPlusInfobaselink(hint, url):
  525.     if url:
  526.         return "%s|%s"%(hint,url)
  527.     return hint
  528.  
  529.  
  530. #---- import the plug-ins ----
  531. import plugins
  532. plugins.LoadPlugins("Q_")
  533. #-----------------------------
  534.  
  535.  
  536. # ----------- REVISION HISTORY ------------
  537. #$Log: qutils.py,v $
  538. #Revision 1.24  2003/12/18 21:51:46  peter-b
  539. #Removed reliance on external string library from Python scripts (second try ;-)
  540. #
  541. #Revision 1.23  2003/12/17 13:58:59  peter-b
  542. #- Rewrote defines for setting Python version
  543. #- Removed back-compatibility with Python 1.5
  544. #- Removed reliance on external string library from Python scripts
  545. #
  546. #Revision 1.22  2003/03/15 01:57:40  tiglari
  547. #add hintPlusInfobaselink function
  548. #
  549. #Revision 1.21  2002/05/11 02:15:41  tiglari
  550. #added attribute-management methods
  551. #
  552. #Revision 1.20  2002/04/12 11:25:30  tiglari
  553. #revert loadimages2 to loadimages  (a less well-thought-out leak hunt move ...)
  554. #
  555. #Revision 1.19  2002/03/26 22:19:20  tiglari
  556. #support UseIntegralVertexes flag
  557. #
  558. #Revision 1.18  2002/03/05 11:03:50  tiglari
  559. #revert group icon selection code to older version to restore hidden/nonhidden
  560. # difference.
  561. #
  562. #Revision 1.17  2001/10/22 11:27:26  tiglari
  563. #clean up some leak tracking stuff
  564. #
  565. #Revision 1.16  2001/10/22 10:28:20  tiglari
  566. #live pointer hunt, revise icon loading
  567. #
  568. #Revision 1.15  2001/10/16 11:40:34  tiglari
  569. #live pointer hunt, delete some stuff after use, very provisional
  570. #
  571. #Revision 1.14  2001/07/28 05:29:19  tiglari
  572. #fix loading of bsp support so that it works after a map has been edited.
  573. #rename patchLoad to reLoad
  574. #
  575. #Revision 1.13  2001/07/27 11:31:47  tiglari
  576. #bsp study: plane viewing, faces in treeview
  577. #
  578. #Revision 1.12  2001/03/29 04:42:11  tiglari
  579. #reinstate MapHotKey & MapHotKeyList
  580. #
  581. #Revision 1.11  2001/03/29 01:25:53  aiv
  582. #modifable :form objects!
  583. #
  584. #Revision 1.8  2001/03/01 19:15:14  decker_dk
  585. #changed loadmapeditor() so it reads the 'BezierPatchSupport' and 'BezierPatchPluginPrefixes' instead.
  586. #
  587. #Revision 1.7  2000/11/19 15:33:02  decker_dk
  588. #Comment about keeping the constants equal with the .PAS source
  589. #
  590. #Revision 1.6  2000/10/26 18:14:34  tiglari
  591. #added SO_BRUSHPRIM
  592. #
  593. #Revision 1.5  2000/06/09 23:39:02  aiv
  594. #More MD3 Support Stuff
  595. #
  596. #Revision 1.4  2000/06/02 16:00:22  alexander
  597. #added cvs headers
  598. #
  599. #Revision 1.3  2000/05/26 23:13:37  tiglari
  600. #Changed patch support loading (loadmapeditor) so that it is loaded when you open a map whose game has shaders
  601. #
  602. #
  603.